/**
 * 
 */
package com.yukh.framework.iso8583.ccbsh;

import java.io.IOException;
import java.io.InputStream;

import org.jpos.iso.BcdPrefixer;
import org.jpos.iso.ISOComponent;
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOStringFieldPackager;
import org.jpos.iso.Interpreter;
import org.jpos.iso.NullPadder;
import org.jpos.iso.Padder;
import org.jpos.iso.Prefixer;

/**
 * @project: Posp
 * @description:
 * @author qingrong.pan(qingrong.pan@99bill.com)
 *
 */
public class IST_IFB_LLLCHAR extends ISOStringFieldPackager {
	private Padder padder = NullPadder.INSTANCE;
    private Prefixer prefixer = BcdPrefixer.LLL;
    private Interpreter interpreter = AsciiInterpreter.INSTANCE;
    
    /**
     * @param len - field len
     * @param description symbolic descrption
     */
    public IST_IFB_LLLCHAR(int len, String description) {
        super(len, description, NullPadder.INSTANCE, AsciiInterpreter.INSTANCE, BcdPrefixer.LLL);
        checkLength(len, 999);
    }
    
    public void setLength(int len)
    {
        checkLength(len, 999);
        super.setLength(len);
    }
    
    /** Create a nice readable message for errors */
    private String makeExceptionMessage(ISOComponent c, String operation) {
        Object fieldKey = "unknown";
        if (c != null)
        {
            try
            {
                fieldKey = c.getKey();
            } catch (Exception ignore)
            {
            }
        }
        return this.getClass().getName() + ": Problem " + operation + " field " + fieldKey;
    }
	@Override
	public byte[] pack(ISOComponent c) throws ISOException {
		try
        {
            String data = (String)c.getValue();
            byte[] dataBytes = data.getBytes("GBK");
            if (dataBytes.length > getLength())
            {
                throw new ISOException("Field length " + dataBytes.length + " too long. Max: " + getLength());
            }
            String paddedData = padder.pad(data, getLength());
            byte[] paddedDataBytes = paddedData.getBytes("GBK");
            byte[] rawData = new byte[prefixer.getPackedLength()
                    + interpreter.getPackedLength(paddedDataBytes.length)];
            
            prefixer.encodeLength(paddedDataBytes.length, rawData);
            interpreter.interpret(paddedData, rawData, prefixer.getPackedLength());
            return rawData;
        } catch(Exception e)
        {
        	e.printStackTrace();
        	throw new ISOException(makeExceptionMessage(c, "packing"), e);
        }
	}

	@Override
	public int unpack(ISOComponent c, byte[] b, int offset) throws ISOException {
		try
        {
            int len = prefixer.decodeLength(b, offset);
            if (len == -1)
            {
                // The prefixer doesn't know how long the field is, so use
    			// maxLength instead
                len = getLength();
            }
            int lenLen = prefixer.getPackedLength();
            String unpacked = interpreter.uninterpret(b, offset + lenLen, len);
            c.setValue(unpacked);
            return lenLen + interpreter.getPackedLength(len);
        } catch(Exception e)
        {
            throw new ISOException(makeExceptionMessage(c, "unpacking"), e);
        }
    }

	@Override
	public void unpack(ISOComponent c, InputStream in) throws IOException,
			ISOException {
		try
        {
            int lenLen = prefixer.getPackedLength ();
            int len;
            if (lenLen == 0)
            {
                len = getLength();
            } else
            {
                len = prefixer.decodeLength (readBytes (in, lenLen), 0);
            }
            int packedLen = interpreter.getPackedLength(len);
            String unpacked = interpreter.uninterpret(readBytes (in, packedLen), 0, len);
            c.setValue(unpacked);
        } catch(ISOException e)
        {
            throw new ISOException(makeExceptionMessage(c, "unpacking"), e);
        }
	}
	
	
	

}
